
import logging
import math
from ctypes import c_float

from PySide6.QtCore import QTimer
from PySide6.QtGui import QSurfaceFormat, QOpenGLFunctions
from PySide6.QtOpenGL import QOpenGLShaderProgram, QOpenGLShader
from PySide6.QtOpenGLWidgets import QOpenGLWidget

# 配置日志记录器

logging.getLogger('OpenGL').setLevel(logging.WARNING)
#logging.getLogger('OpenGL_accelerate').setLevel(logging.WARNING)
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
日志记录器 = logging.getLogger(__name__)
from OpenGL import GL

class OpenGL加速组件(QOpenGLWidget, QOpenGLFunctions):
    """
    OpenGL加速组件类，负责初始化OpenGL和渲染3D图形
    """

    def __init__(self, parent=None):
        super().__init__(parent)
        QOpenGLFunctions.__init__(self)
        self.调试模式 = False  # 设置调试模式开关

        # 设置日志等级
        if self.调试模式:
            日志记录器.setLevel(logging.DEBUG)
            日志记录器.debug(f"{self.__class__.__name__}调试模式已开启")
        else:

            日志记录器.setLevel(logging.ERROR)  # 只显示警告及以上级别的日志

        日志记录器.info("OpenGL加速组件已初始化")

        # 设置OpenGL版本和配置
        format = QSurfaceFormat()
        format.setRenderableType(QSurfaceFormat.RenderableType.DefaultRenderableType)
        format.setVersion(3, 3)
        format.setProfile(QSurfaceFormat.OpenGLContextProfile.CoreProfile)
        format.setSamples(4)
        format.setOption(QSurfaceFormat.FormatOption.DebugContext, True)
        self.setFormat(format)

        self.program = None
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update)
        self.timer.start(16)  # 大约 60 FPS
        self.rotation_angle = 0.0

    def initializeGL(self):
        """
        初始化OpenGL函数和资源
        """
        self.initializeOpenGLFunctions()
        # 初始化OpenGL函数和资源
        日志记录器.info("OpenGL Version: %s", self.glGetString(GL.GL_VERSION))
        日志记录器.info("OpenGL Vendor: %s", self.glGetString(GL.GL_VENDOR))

        # 创建并编译着色器程序
        self.program = QOpenGLShaderProgram(self)
        if not self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Vertex, """
            #version 330 core
            layout(location = 0) in vec3 aPos;
            uniform mat4 model;
            void main()
            {
                gl_Position = model * vec4(aPos, 1.0);
            }
        """):
            日志记录器.error("错误: 不能添加顶点着色器")
            return

        if not self.program.addShaderFromSourceCode(QOpenGLShader.ShaderTypeBit.Fragment, """
            #version 330 core
            out vec4 FragColor;
            void main()
            {
                FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
            }
        """):
            日志记录器.error("错误: 不能添加片段着色器")
            return

        if not self.program.link():
            日志记录器.error("错误: 着色器程序链接失败")
            return

        self.model_loc = self.program.uniformLocation("model")

        # 设置顶点数据
        vertex_data = [
            -0.5, -0.5, 0.0,
            0.5, -0.5, 0.0,
            0.0, 0.5, 0.0
        ]
        self.vbo = GL.glGenBuffers(1)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
        GL.glBufferData(GL.GL_ARRAY_BUFFER, len(vertex_data) * 4, (c_float * len(vertex_data))(*vertex_data), GL.GL_STATIC_DRAW)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)

        # 创建并绑定VAO
        self.vao = GL.glGenVertexArrays(1)
        GL.glBindVertexArray(self.vao)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
        GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, None)
        GL.glEnableVertexAttribArray(0)
        GL.glBindVertexArray(0)

    def paintGL(self):
        """
        执行OpenGL绘制
        """
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        self.program.bind()

        # 计算旋转矩阵
        rotation = math.radians(self.rotation_angle)
        model = (
            math.cos(rotation), -math.sin(rotation), 0.0, 0.0,
            math.sin(rotation), math.cos(rotation), 0.0, 0.0,
            0.0, 0.0, 1.0, 0.0,
            0.0, 0.0, 0.0, 1.0
        )
        self.program.setUniformValue(self.model_loc, (c_float * 16)(*model))
        GL.glBindVertexArray(self.vao)
        GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
        GL.glBindVertexArray(0)
        self.program.release()

        # 更新旋转角度
        self.rotation_angle += 1.0
        日志记录器.debug("更新旋转角度: %f", self.rotation_angle)

    def resizeGL(self, width, height):
        """
        调整OpenGL视口
        """
        GL.glViewport(0, 0, width, height)
        日志记录器.info("调整视口大小: %d x %d", width, height)
